Skip to content

Conversation

@bricknerb
Copy link
Contributor

Also, remove the non-const ASTUnit::getASTContext() since it's no longer necessary.
This would make it similar to Decl::getAstContext() const for a more consistent and flexible API.

…text`

Also, remove the non-const `ASTUnit::getASTContext()` since it's no longer necessary.
This would make it similar to `Decl::getAstContext() const` for a more consistent and flexible API.
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Mar 6, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 6, 2025

@llvm/pr-subscribers-clang

Author: Boaz Brickner (bricknerb)

Changes

Also, remove the non-const ASTUnit::getASTContext() since it's no longer necessary.
This would make it similar to Decl::getAstContext() const for a more consistent and flexible API.


Full diff: https://github.com/llvm/llvm-project/pull/130096.diff

1 Files Affected:

  • (modified) clang/include/clang/Frontend/ASTUnit.h (+1-2)
diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h
index 1f98c6ab328ba..bd55c8b627941 100644
--- a/clang/include/clang/Frontend/ASTUnit.h
+++ b/clang/include/clang/Frontend/ASTUnit.h
@@ -439,8 +439,7 @@ class ASTUnit {
   Preprocessor &getPreprocessor() { return *PP; }
   std::shared_ptr<Preprocessor> getPreprocessorPtr() const { return PP; }
 
-  const ASTContext &getASTContext() const { return *Ctx; }
-  ASTContext &getASTContext() { return *Ctx; }
+  ASTContext &getASTContext() const { return *Ctx; }
 
   void setASTContext(ASTContext *ctx) { Ctx = ctx; }
   void setPreprocessor(std::shared_ptr<Preprocessor> pp);

@bricknerb bricknerb requested a review from dwblaikie March 6, 2025 12:54
Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is weakening const correctness, which is the opposite direction of where we should be going IMO.

Copy link
Contributor

@Endilll Endilll left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Aaron that this patch doesn't move us towards the direction we generally want. I'd like to see more justification than 2 lines in the description.

@mizvekov
Copy link
Contributor

mizvekov commented Mar 6, 2025

There is no const_cast, or casting away const in any form on this patch, so how does it weaken const correctness?

@mizvekov
Copy link
Contributor

mizvekov commented Mar 6, 2025

To put it another way, what do we want to prevent the user from accomplishing if he obtains a non-const reference to ASTContext from a const ASTUnit?

@AaronBallman
Copy link
Collaborator

There is no const_cast, or casting away const in any form on this patch, so how does it weaken const correctness?

When a function is marked as const, the implication is that calling the function should not lead to an underlying mutation. Given that this function is returning data it holds (*Ctx), the expectation is that the return value is also const-qualified. The typical pattern is to have an overload set as in the original code -- the non-const version can return something which can mutate, the const version can return something which doesn't allow for mutation without casting away the constness.

@bricknerb
Copy link
Contributor Author

Thanks for the feedback!

Is there a way to call ASTContext::createMangleContext() when I have a const ASTUnit?
I've tried to make ASTContext::createMangleContext() const but this failed as it seems to actually call methods that potentially modify the context.

However, when I have a const Decl, I can just call getAstContext().createMangleContext().

@AaronBallman
Copy link
Collaborator

Thanks for the feedback!

Is there a way to call ASTContext::createMangleContext() when I have a const ASTUnit? I've tried to make ASTContext::createMangleContext() const but this failed as it seems to actually call methods that potentially modify the context.

However, when I have a const Decl, I can just call getAstContext().createMangleContext().

There's two answers. In a world where we have const correctness, you shouldn't be able to (this is a misfeature on Decl that it has a const overload that returns a const ASTContext &). However, Clang inherited a lack of const correctness from the mists of time, so we have these sort of misfeatures still lurking (and will for quite some time). So for now, the recommendation is const_cast so it's clear where we're breaking const correctness.

Copy link
Collaborator

@shafik shafik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just throwing in my $0.02 and saying I agree w/ Aaron and Vlad here, this is not the right direction. Having a const method return a non-const that we will then mutate is just not clean code.

Having to use const_cast documents we are violating expectations and marks this as something we need to clean up in the future.

@bricknerb
Copy link
Contributor Author

Thanks everyone!
Closing this.

@bricknerb bricknerb closed this Mar 7, 2025
bricknerb added a commit to bricknerb/carbon-lang that referenced this pull request Mar 10, 2025
This is a followup of [a comment](https://github.com/carbon-language/carbon-lang/pull/5062/files/89e56d51858bcc18d4242d4e5c9ee0e7496d887e#r1979993815) in carbon-language#5062.

Change `File::cpp_ast()` to be `const` while keeping it returning a non-const pointer to `clang::ASTUnit`.
This makes the fact we use [Clang with lack of const correctness](llvm/llvm-project#130096 (comment)) explicit.

Alternatives:
* Change `ASTUnit::getASTContext() const` to return a non-const `ASTContext`. [Rejected due to weakening const correctness](llvm/llvm-project#130096).
* Change `createMangleContext()` to be `const`. Tried that and it seems like it relies heavily on non const API.
* Change Clang `MangleContext::mangleName()` to `const`.
* Use `const_cast` on `ASTContext` when calling `createMangleContext()`.
github-merge-queue bot pushed a commit to carbon-language/carbon-lang that referenced this pull request Mar 12, 2025
This is a followup of [a
comment](https://github.com/carbon-language/carbon-lang/pull/5062/files/89e56d51858bcc18d4242d4e5c9ee0e7496d887e#r1979993815)
in #5062.

Add a mutable AST pointer to `FileContext`.

This is necessary since we use [Clang with lack of const
correctness](llvm/llvm-project#130096 (comment)).

Alternatives in Clang:
* Change `ASTUnit::getASTContext() const` to return a non-const
`ASTContext`. [Tried and was rejected upstream due to weakening const
correctness](llvm/llvm-project#130096).
* Change `createMangleContext()` to be `const`. Tried that and it seems
like it relies heavily on non const API.
* Change `MangleContext::mangleName()` to `const`. Tried that but there
are several lazy initialization and id creations happening that modify
the context. See details in
llvm/llvm-project#130613.

Alternatives in Carbon:
* Use `const_cast` on `ASTContext` when calling `createMangleContext()`.
* Make `FileContext::sem_ir_` point to a mutable `SemIR::File`.
* Change `File::cpp_ast()` to be const while keeping it return a mutable
pointer.

Part of #4666.
@bricknerb bricknerb deleted the ast branch November 4, 2025 10:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants